/* Copyright (c) 2022 渝州大数据实验室
 *
 * Lanius is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.yzbdl.lanius.orchestrate.serv.service.resource.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.yzbdl.lanius.orchestrate.serv.dto.resource.TaskResourceConfigPageDto;
import org.yzbdl.lanius.orchestrate.serv.entity.resource.TaskResourceConfigEntity;
import org.yzbdl.lanius.orchestrate.serv.entity.resource.TaskResourceEntity;
import org.yzbdl.lanius.orchestrate.serv.enums.ResourceDataStatusEnum;
import org.yzbdl.lanius.orchestrate.serv.mapper.resource.TaskResourceConfigMapper;
import org.yzbdl.lanius.orchestrate.serv.mapper.resource.TaskResourceMapper;
import org.yzbdl.lanius.orchestrate.serv.service.resource.TaskResourceConfigService;
import org.yzbdl.lanius.orchestrate.serv.service.resource.TaskResourceService;
import org.yzbdl.lanius.orchestrate.serv.utils.JdbcUtil;
import org.yzbdl.lanius.orchestrate.common.exception.runtime.BusinessException;
import org.yzbdl.lanius.orchestrate.common.utils.ExceptionUtil;
import org.yzbdl.lanius.orchestrate.common.utils.SpecialCharacterUtil;

import java.util.Objects;

/**
 * @author zhuhongji@yzbdl.ac.cn
 * @since 2022-04-08 16:14
 */
@Service
@AllArgsConstructor
public class TaskResourceConfigServiceImpl extends ServiceImpl<TaskResourceConfigMapper, TaskResourceConfigEntity> implements TaskResourceConfigService {

	private final TaskResourceMapper taskResourceMapper;

	private final TaskResourceService taskResourceService;

	@Override
	public Boolean addTaskResourceConfig(TaskResourceConfigEntity taskResourceConfigEntity) {
		// 重命名判断
		LambdaQueryWrapper<TaskResourceConfigEntity> queryWrapper = new QueryWrapper<TaskResourceConfigEntity>().lambda()
				.eq(TaskResourceConfigEntity::getConnectName, taskResourceConfigEntity.getConnectName())
				.eq(TaskResourceConfigEntity::getDeleted, false);
		ExceptionUtil.checkParam(!this.baseMapper.exists(queryWrapper), "已存在同样的资源库名称，请重新输入！");
		LambdaQueryWrapper<TaskResourceConfigEntity> query = new QueryWrapper<TaskResourceConfigEntity>().lambda()
				.eq(TaskResourceConfigEntity::getConnectUrl, taskResourceConfigEntity.getConnectUrl())
				.eq(TaskResourceConfigEntity::getConnectAccount, taskResourceConfigEntity.getConnectAccount())
				.eq(TaskResourceConfigEntity::getDeleted, false);
		ExceptionUtil.checkParam(!this.baseMapper.exists(query),
				"已存在链接地址、连接用户两项同时相同的资源配置，请重新输入！");
		if(Objects.isNull(taskResourceConfigEntity.getStatus())){
			taskResourceConfigEntity.setStatus(ResourceDataStatusEnum.NORMAL.getCode());
		}
		taskResourceConfigEntity.setDeleted(false);
		return this.save(taskResourceConfigEntity);
	}

	@Override
	public Boolean deleteTaskResourceConfig(Long id) {
		LambdaQueryWrapper<TaskResourceEntity> queryWrapper = new QueryWrapper<TaskResourceEntity>().lambda()
				.eq(TaskResourceEntity::getResourceConfigId, id)
				.eq(TaskResourceEntity::getDeleted, false);
		if(taskResourceMapper.exists(queryWrapper)){
			throw new BusinessException("该资源库中数据已被任务调用！");
		}
		return this.updateById(TaskResourceConfigEntity.builder().id(id).deleted(true).build());
	}

	@Override
	public TaskResourceConfigEntity getTaskResourceConfig(Long id) {
		return this.getById(id);
	}

    @Override
    public IPage<TaskResourceConfigEntity> pageTaskResourceConfig(Integer page, Integer size,
        TaskResourceConfigPageDto taskResourceConfigPageDto) {
        Page<TaskResourceConfigEntity> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<TaskResourceConfigEntity> queryWrapper =
            new QueryWrapper<TaskResourceConfigEntity>().lambda()
                // 模糊匹配资源库名称
                .like(StringUtils.hasLength(taskResourceConfigPageDto.getConnectName()),
                    TaskResourceConfigEntity::getConnectName, SpecialCharacterUtil.escapeStr(taskResourceConfigPageDto.getConnectName()))
                .eq(TaskResourceConfigEntity::getDeleted, false)
		        // 筛选任务资源配置状态
                .eq(Objects.nonNull(taskResourceConfigPageDto.getStatus()), TaskResourceConfigEntity::getStatus,
                    taskResourceConfigPageDto.getStatus())
                .orderByDesc(TaskResourceConfigEntity::getCreateTime).orderByDesc(TaskResourceConfigEntity::getId);
        return this.page(pageParam, queryWrapper);
    }

	@Override
	public Boolean updateTaskResourceConfig(TaskResourceConfigEntity taskResourceConfigEntity) {
		ExceptionUtil.checkParam(Objects.nonNull(taskResourceConfigEntity.getId()), "id不能为空");
		// 重命名判断
		LambdaQueryWrapper<TaskResourceConfigEntity> queryWrapper = new QueryWrapper<TaskResourceConfigEntity>().lambda()
				.ne(TaskResourceConfigEntity::getId, taskResourceConfigEntity.getId())
				.eq(TaskResourceConfigEntity::getConnectName, taskResourceConfigEntity.getConnectName())
				.eq(TaskResourceConfigEntity::getDeleted, false);
		ExceptionUtil.checkParam(!this.baseMapper.exists(queryWrapper), "已存在同样的资源库名称，请重新输入！");
		LambdaQueryWrapper<TaskResourceConfigEntity> query = new QueryWrapper<TaskResourceConfigEntity>().lambda()
				.ne(TaskResourceConfigEntity::getId, taskResourceConfigEntity.getId())
				.eq(TaskResourceConfigEntity::getConnectUrl, taskResourceConfigEntity.getConnectUrl())
				.eq(TaskResourceConfigEntity::getConnectAccount, taskResourceConfigEntity.getConnectAccount())
				.eq(TaskResourceConfigEntity::getDeleted, false);
		ExceptionUtil.checkParam(!this.baseMapper.exists(query),
				"已存在链接地址、连接用户两项同时相同的资源配置，请重新输入！");
		// 更新任务资源相关数据
		TaskResourceConfigEntity oldEntity = this.getById(taskResourceConfigEntity.getId());
		if(StringUtils.hasLength(taskResourceConfigEntity.getConnectUrl()) &&
				!taskResourceConfigEntity.getConnectUrl().equals(oldEntity.getConnectUrl())){
			taskResourceService.batchUpdateResourceContent(taskResourceConfigEntity.getId(),
					JdbcUtil.getDbName(JdbcUtil.parseJdbcUrl(taskResourceConfigEntity.getConnectUrl())));
		}
		return this.updateById(taskResourceConfigEntity);
	}

}
